From 278ab3c4debcd7c10b502ea51f7cff43e210218a Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Sat, 31 Mar 2018 17:22:48 +0200 Subject: [PATCH] snapshot: Track clip as a rect only --- gtk/gskpango.c | 19 +--- gtk/gtkiconview.c | 11 +- gtk/gtksnapshot.c | 232 +++++++++++++-------------------------- gtk/gtksnapshot.h | 2 +- gtk/gtksnapshotprivate.h | 4 +- gtk/gtkwidget.c | 10 +- 6 files changed, 99 insertions(+), 179 deletions(-) diff --git a/gtk/gskpango.c b/gtk/gskpango.c index 7e7fa73ebe..7c2aa4dee3 100644 --- a/gtk/gskpango.c +++ b/gtk/gskpango.c @@ -126,25 +126,18 @@ gsk_pango_renderer_show_text_glyphs (PangoRenderer *renderer, if (ink_rect.width == 0 || ink_rect.height == 0) return; - gtk_snapshot_get_offset (crenderer->snapshot, &x_offset, &y_offset); - graphene_rect_init (&node_bounds, - x_offset + (float)x/PANGO_SCALE, - y_offset + (float)y/PANGO_SCALE + ink_rect.y, + (float)x/PANGO_SCALE, + (float)y/PANGO_SCALE + ink_rect.y, ink_rect.x + ink_rect.width, ink_rect.height); - /* Remove the snapshot offset from the position here again since - * gtk_snapshot_clips_rect will apply it to the given rect. */ - if (gtk_snapshot_clips_rect (crenderer->snapshot, - &(cairo_rectangle_int_t){ - node_bounds.origin.x - x_offset, - node_bounds.origin.y - y_offset, - ceil (node_bounds.size.width), - ceil (node_bounds.size.height) - })) + if (gtk_snapshot_clips_rect (crenderer->snapshot, &node_bounds)) return; + gtk_snapshot_get_offset (crenderer->snapshot, &x_offset, &y_offset); + graphene_rect_offset (&node_bounds, x_offset, y_offset); + get_color (crenderer, PANGO_RENDER_PART_FOREGROUND, &color); node = gsk_text_node_new_with_bounds (font, diff --git a/gtk/gtkiconview.c b/gtk/gtkiconview.c index 4c431e1b96..a9a9901bcb 100644 --- a/gtk/gtkiconview.c +++ b/gtk/gtkiconview.c @@ -1684,12 +1684,13 @@ gtk_icon_view_snapshot (GtkWidget *widget, for (icons = icon_view->priv->items; icons; icons = icons->next) { GtkIconViewItem *item = icons->data; - cairo_rectangle_int_t area; + graphene_rect_t area; - area.x = item->cell_area.x - icon_view->priv->item_padding; - area.y = item->cell_area.y - icon_view->priv->item_padding; - area.width = item->cell_area.width + icon_view->priv->item_padding * 2; - area.height = item->cell_area.height + icon_view->priv->item_padding * 2; + graphene_rect_init (&area, + item->cell_area.x - icon_view->priv->item_padding, + item->cell_area.y - icon_view->priv->item_padding, + item->cell_area.width + icon_view->priv->item_padding * 2, + item->cell_area.height + icon_view->priv->item_padding * 2); if (!gtk_snapshot_clips_rect (snapshot, &area)) { diff --git a/gtk/gtksnapshot.c b/gtk/gtksnapshot.c index 4a0cdd9865..ead1e5acaf 100644 --- a/gtk/gtksnapshot.c +++ b/gtk/gtksnapshot.c @@ -81,22 +81,6 @@ gtk_snapshot_init (GtkSnapshot *self) { } -static cairo_region_t * -create_offset_region (const cairo_region_t *region, - int dx, - int dy) -{ - cairo_region_t *result; - - if (region == NULL) - return NULL; - - result = cairo_region_copy (region); - cairo_region_translate (result, -dx, -dy); - - return result; -} - static GskRenderNode * gtk_snapshot_collect_default (GtkSnapshot *snapshot, GtkSnapshotState *state, @@ -127,7 +111,7 @@ gtk_snapshot_collect_default (GtkSnapshot *snapshot, static GtkSnapshotState * gtk_snapshot_push_state (GtkSnapshot *snapshot, char *name, - cairo_region_t *clip, + const graphene_rect_t *clip, int translate_x, int translate_y, GtkSnapshotCollectFunc collect_func) @@ -139,7 +123,10 @@ gtk_snapshot_push_state (GtkSnapshot *snapshot, state->name = name; if (clip) - state->clip_region = cairo_region_reference (clip); + { + state->clip = *clip; + state->has_clip = TRUE; + } state->translate_x = translate_x; state->translate_y = translate_y; state->collect_func = collect_func; @@ -168,14 +155,13 @@ gtk_snapshot_get_previous_state (const GtkSnapshot *snapshot) static void gtk_snapshot_state_clear (GtkSnapshotState *state) { - g_clear_pointer (&state->clip_region, cairo_region_destroy); g_clear_pointer (&state->name, g_free); } static GtkSnapshot * -gtk_snapshot_new_internal (gboolean record_names, - cairo_region_t *clip, - char *name) +gtk_snapshot_new_internal (gboolean record_names, + const graphene_rect_t *clip, + char *name) { GtkSnapshot *snapshot; @@ -235,7 +221,7 @@ gtk_snapshot_new_child (GtkSnapshot *parent, { GtkSnapshotState *parent_state; GtkSnapshot *snapshot; - cairo_region_t *clip; + graphene_rect_t c, *clip; char *str; if (name && parent->record_names) @@ -250,17 +236,21 @@ gtk_snapshot_new_child (GtkSnapshot *parent, str = NULL; parent_state = gtk_snapshot_get_current_state (parent); - clip = create_offset_region (parent_state->clip_region, - parent_state->translate_x, - parent_state->translate_y); + if (parent_state->has_clip) + { + graphene_rect_offset_r (&parent_state->clip, + - parent_state->translate_x, + - parent_state->translate_y, + &c); + clip = &c; + } + else + clip = NULL; snapshot = gtk_snapshot_new_internal (parent->record_names, clip, str); - if (clip) - cairo_region_destroy (clip); - return snapshot; } @@ -341,7 +331,7 @@ gtk_snapshot_push (GtkSnapshot *snapshot, gtk_snapshot_push_state (snapshot, g_strdup (str), - state->clip_region, + state->has_clip ? &state->clip : NULL, state->translate_x, state->translate_y, gtk_snapshot_collect_default); @@ -453,7 +443,7 @@ gtk_snapshot_push_offset (GtkSnapshot *snapshot) { GtkSnapshotState *state = gtk_snapshot_get_current_state (snapshot); char *str; - cairo_region_t *offset_clip; + graphene_rect_t clip; if (snapshot->record_names) { @@ -462,17 +452,17 @@ gtk_snapshot_push_offset (GtkSnapshot *snapshot) else str = NULL; - offset_clip = create_offset_region (state->clip_region, - state->translate_x, - state->translate_y); + if (state->has_clip) + graphene_rect_offset_r (&state->clip, + - state->translate_x, + - state->translate_y, + &clip); state = gtk_snapshot_push_state (snapshot, str, - offset_clip, + state->has_clip ? &clip : NULL, 0, 0, gtk_snapshot_collect_offset); - if (offset_clip) - cairo_region_destroy (offset_clip); } static GskRenderNode * @@ -531,7 +521,7 @@ gtk_snapshot_push_opacity (GtkSnapshot *snapshot, state = gtk_snapshot_push_state (snapshot, str, - current_state->clip_region, + current_state->has_clip ? ¤t_state->clip : NULL, current_state->translate_x, current_state->translate_y, gtk_snapshot_collect_opacity); @@ -589,7 +579,7 @@ gtk_snapshot_push_blur (GtkSnapshot *snapshot, state = gtk_snapshot_push_state (snapshot, str, - current_state->clip_region, + current_state->has_clip ? ¤t_state->clip : NULL, current_state->translate_x, current_state->translate_y, gtk_snapshot_collect_blur); @@ -675,11 +665,11 @@ gtk_snapshot_push_color_matrix (GtkSnapshot *snapshot, str = NULL; state = gtk_snapshot_push_state (snapshot, - str, - current_state->clip_region, - current_state->translate_x, - current_state->translate_y, - gtk_snapshot_collect_color_matrix); + str, + current_state->has_clip ? ¤t_state->clip : NULL, + current_state->translate_x, + current_state->translate_y, + gtk_snapshot_collect_color_matrix); graphene_matrix_init_from_matrix (&state->data.color_matrix.matrix, color_matrix); graphene_vec4_init_from_vec4 (&state->data.color_matrix.offset, color_offset); @@ -731,7 +721,6 @@ gtk_snapshot_push_repeat (GtkSnapshot *snapshot, { const GtkSnapshotState *current_state = gtk_snapshot_get_current_state (snapshot); GtkSnapshotState *state; - cairo_region_t *clip = NULL; graphene_rect_t real_child_bounds = { { 0 } }; char *str; @@ -747,16 +736,11 @@ gtk_snapshot_push_repeat (GtkSnapshot *snapshot, str = NULL; if (child_bounds) - { - cairo_rectangle_int_t rect; - graphene_rect_offset_r (child_bounds, current_state->translate_x, current_state->translate_y, &real_child_bounds); - rectangle_init_from_graphene (&rect, &real_child_bounds); - clip = cairo_region_create_rectangle (&rect); - } + graphene_rect_offset_r (child_bounds, current_state->translate_x, current_state->translate_y, &real_child_bounds); state = gtk_snapshot_push_state (snapshot, str, - clip, + &real_child_bounds, current_state->translate_x, current_state->translate_y, gtk_snapshot_collect_repeat); @@ -767,9 +751,6 @@ gtk_snapshot_push_repeat (GtkSnapshot *snapshot, state->data.repeat.child_bounds = real_child_bounds; current_state = state; - - if (clip) - cairo_region_destroy (clip); } static GskRenderNode * @@ -810,8 +791,7 @@ gtk_snapshot_push_clip (GtkSnapshot *snapshot, { const GtkSnapshotState *current_state = gtk_snapshot_get_current_state (snapshot); GtkSnapshotState *state; - graphene_rect_t real_bounds; - cairo_region_t *clip; + graphene_rect_t clip, real_bounds; cairo_rectangle_int_t rect; char *str; @@ -829,25 +809,19 @@ gtk_snapshot_push_clip (GtkSnapshot *snapshot, str = NULL; rectangle_init_from_graphene (&rect, &real_bounds); - if (current_state->clip_region) - { - clip = cairo_region_copy (current_state->clip_region); - cairo_region_intersect_rectangle (clip, &rect); - } + if (current_state->has_clip) + graphene_rect_intersection (¤t_state->clip, &real_bounds, &clip); else - { - clip = cairo_region_create_rectangle (&rect); - } + clip = real_bounds; + state = gtk_snapshot_push_state (snapshot, - str, - clip, - current_state->translate_x, - current_state->translate_y, - gtk_snapshot_collect_clip); + str, + &clip, + current_state->translate_x, + current_state->translate_y, + gtk_snapshot_collect_clip); state->data.clip.bounds = real_bounds; - - cairo_region_destroy (clip); } static GskRenderNode * @@ -905,8 +879,7 @@ gtk_snapshot_push_rounded_clip (GtkSnapshot *snapshot, const GtkSnapshotState *current_state = gtk_snapshot_get_current_state (snapshot); GtkSnapshotState *state; GskRoundedRect real_bounds; - cairo_region_t *clip; - cairo_rectangle_int_t rect; + graphene_rect_t clip; char *str; gsk_rounded_rect_init_copy (&real_bounds, bounds); @@ -923,29 +896,20 @@ gtk_snapshot_push_rounded_clip (GtkSnapshot *snapshot, else str = NULL; - rectangle_init_from_graphene (&rect, &real_bounds.bounds); - if (current_state->clip_region) - { - clip = cairo_region_copy (current_state->clip_region); - cairo_region_intersect_rectangle (clip, &rect); - } + if (current_state->has_clip) + graphene_rect_intersection (¤t_state->clip, &real_bounds.bounds, &clip); else - { - clip = cairo_region_create_rectangle (&rect); - } + clip = real_bounds.bounds; state = gtk_snapshot_push_state (snapshot, - str, - clip, - current_state->translate_x, - current_state->translate_y, - gtk_snapshot_collect_rounded_clip); + str, + &clip, + current_state->translate_x, + current_state->translate_y, + gtk_snapshot_collect_rounded_clip); state->data.rounded_clip.bounds = real_bounds; - - current_state = state; - cairo_region_destroy (clip); } static GskRenderNode * @@ -999,7 +963,7 @@ gtk_snapshot_push_shadow (GtkSnapshot *snapshot, state = gtk_snapshot_push_state (snapshot, str, - current_state->clip_region, + current_state->has_clip ? ¤t_state->clip : NULL, current_state->translate_x, current_state->translate_y, gtk_snapshot_collect_shadow); @@ -1102,7 +1066,7 @@ gtk_snapshot_push_blend (GtkSnapshot *snapshot, top_state = gtk_snapshot_push_state (snapshot, str, - current_state->clip_region, + current_state->has_clip ? ¤t_state->clip : NULL, current_state->translate_x, current_state->translate_y, gtk_snapshot_collect_blend_top); @@ -1110,7 +1074,7 @@ gtk_snapshot_push_blend (GtkSnapshot *snapshot, gtk_snapshot_push_state (snapshot, g_strdup (str), - top_state->clip_region, + top_state->has_clip ? &top_state->clip : NULL, top_state->translate_x, top_state->translate_y, gtk_snapshot_collect_blend_bottom); @@ -1227,7 +1191,7 @@ gtk_snapshot_push_cross_fade (GtkSnapshot *snapshot, end_state = gtk_snapshot_push_state (snapshot, str, - current_state->clip_region, + current_state->has_clip ? ¤t_state->clip : NULL, current_state->translate_x, current_state->translate_y, gtk_snapshot_collect_cross_fade_end); @@ -1235,7 +1199,7 @@ gtk_snapshot_push_cross_fade (GtkSnapshot *snapshot, gtk_snapshot_push_state (snapshot, g_strdup (str), - end_state->clip_region, + end_state->has_clip ? &end_state->clip : NULL, end_state->translate_x, end_state->translate_y, gtk_snapshot_collect_cross_fade_start); @@ -1499,18 +1463,8 @@ gtk_snapshot_append_cairo (GtkSnapshot *snapshot, graphene_rect_offset_r (bounds, current_state->translate_x, current_state->translate_y, &real_bounds); - if (current_state->clip_region) - { - cairo_rectangle_int_t clip_extents; - cairo_region_get_extents (current_state->clip_region, &clip_extents); - graphene_rect_intersection (&GRAPHENE_RECT_INIT ( - clip_extents.x, - clip_extents.y, - clip_extents.width, - clip_extents.height - ), - &real_bounds, &real_bounds); - } + if (current_state->has_clip) + graphene_rect_intersection (¤t_state->clip, &real_bounds, &real_bounds); node = gsk_cairo_node_new (&real_bounds); @@ -1617,18 +1571,8 @@ gtk_snapshot_append_color (GtkSnapshot *snapshot, graphene_rect_offset_r (bounds, current_state->translate_x, current_state->translate_y, &real_bounds); /* Color nodes are trivially "clippable" so we do it now */ - if (current_state->clip_region) - { - cairo_rectangle_int_t clip_extents; - cairo_region_get_extents (current_state->clip_region, &clip_extents); - graphene_rect_intersection (&GRAPHENE_RECT_INIT ( - clip_extents.x, - clip_extents.y, - clip_extents.width, - clip_extents.height - ), - &real_bounds, &real_bounds); - } + if (current_state->has_clip) + graphene_rect_intersection (¤t_state->clip, &real_bounds, &real_bounds); node = gsk_color_node_new (color, &real_bounds); @@ -1660,21 +1604,21 @@ gtk_snapshot_append_color (GtkSnapshot *snapshot, * Returns: %TRUE if @bounds is entirely outside the clip region */ gboolean -gtk_snapshot_clips_rect (GtkSnapshot *snapshot, - const cairo_rectangle_int_t *rect) +gtk_snapshot_clips_rect (GtkSnapshot *snapshot, + const graphene_rect_t *bounds) { const GtkSnapshotState *current_state = gtk_snapshot_get_current_state (snapshot); - cairo_rectangle_int_t offset_rect; + graphene_rect_t offset_rect; - if (current_state->clip_region == NULL) + if (!current_state->has_clip) return FALSE; - offset_rect.x = rect->x + current_state->translate_x; - offset_rect.y = rect->y + current_state->translate_y; - offset_rect.width = rect->width; - offset_rect.height = rect->height; + graphene_rect_offset_r (bounds, + current_state->translate_x, + current_state->translate_y, + &offset_rect); - return cairo_region_contains_rectangle (current_state->clip_region, &offset_rect) == CAIRO_REGION_OVERLAP_OUT; + return !graphene_rect_intersection (&offset_rect, ¤t_state->clip, NULL); } /** @@ -1852,19 +1796,8 @@ gtk_snapshot_append_linear_gradient (GtkSnapshot *snapshot, real_end_point.y = end_point->y + current_state->translate_y; /* Linear gradients can be trivially clipped if we don't change the start/end points. */ - if (current_state->clip_region) - { - cairo_rectangle_int_t clip_extents; - - cairo_region_get_extents (current_state->clip_region, &clip_extents); - graphene_rect_intersection (&GRAPHENE_RECT_INIT ( - clip_extents.x, - clip_extents.y, - clip_extents.width, - clip_extents.height - ), - &real_bounds, &real_bounds); - } + if (current_state->has_clip) + graphene_rect_intersection (¤t_state->clip, &real_bounds, &real_bounds); node = gsk_linear_gradient_node_new (&real_bounds, &real_start_point, @@ -1930,19 +1863,8 @@ gtk_snapshot_append_repeating_linear_gradient (GtkSnapshot *snapshot, real_end_point.y = end_point->y + current_state->translate_y; /* Repeating Linear gradients can be trivially clipped if we don't change the start/end points. */ - if (current_state->clip_region) - { - cairo_rectangle_int_t clip_extents; - - cairo_region_get_extents (current_state->clip_region, &clip_extents); - graphene_rect_intersection (&GRAPHENE_RECT_INIT ( - clip_extents.x, - clip_extents.y, - clip_extents.width, - clip_extents.height - ), - &real_bounds, &real_bounds); - } + if (current_state->has_clip) + graphene_rect_intersection (¤t_state->clip, &real_bounds, &real_bounds); node = gsk_repeating_linear_gradient_node_new (&real_bounds, &real_start_point, diff --git a/gtk/gtksnapshot.h b/gtk/gtksnapshot.h index 05de9ab599..14cb20470d 100644 --- a/gtk/gtksnapshot.h +++ b/gtk/gtksnapshot.h @@ -169,7 +169,7 @@ void gtk_snapshot_append_layout (GtkSnapshot GDK_AVAILABLE_IN_ALL gboolean gtk_snapshot_clips_rect (GtkSnapshot *snapshot, - const cairo_rectangle_int_t *bounds); + const graphene_rect_t *bounds); GDK_AVAILABLE_IN_ALL void gtk_snapshot_render_background (GtkSnapshot *snapshot, diff --git a/gtk/gtksnapshotprivate.h b/gtk/gtksnapshotprivate.h index 3b1a145ae4..e5ddb600f0 100644 --- a/gtk/gtksnapshotprivate.h +++ b/gtk/gtksnapshotprivate.h @@ -35,10 +35,12 @@ struct _GtkSnapshotState { guint start_node_index; guint n_nodes; - cairo_region_t *clip_region; + graphene_rect_t clip; int translate_x; int translate_y; + guint has_clip : 1; + GtkSnapshotCollectFunc collect_func; union { struct { diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c index 14f121b31a..3d9f967ce5 100644 --- a/gtk/gtkwidget.c +++ b/gtk/gtkwidget.c @@ -13815,7 +13815,7 @@ gtk_widget_snapshot (GtkWidget *widget, GtkSnapshot *snapshot) { GtkWidgetPrivate *priv = widget->priv; - cairo_rectangle_int_t offset_clip; + graphene_rect_t offset_clip; double opacity; if (!_gtk_widget_is_drawable (widget)) @@ -13828,9 +13828,11 @@ gtk_widget_snapshot (GtkWidget *widget, } priv = widget->priv; - offset_clip = priv->clip; - offset_clip.x -= priv->allocation.x; - offset_clip.y -= priv->allocation.y; + graphene_rect_init (&offset_clip, + priv->clip.x - priv->allocation.x, + priv->clip.y - priv->allocation.y, + priv->clip.width, + priv->clip.height); if (gtk_snapshot_clips_rect (snapshot, &offset_clip)) return; -- 2.30.2